/**
 * 使用普通的js方案实现slider
 */
export default {
	watch: {
		value(n) {
			// 只有在非滑动状态时，才可以通过value更新滑块值，这里监听，是为了让用户触发
			if (this.status === "end") {
				this.updateSliderPlacement(n, true);
			}
		},
	},
	mounted() {
		this.init();
	},
	methods: {
		init() {
			this.getSliderRect();
		},
		// 获取slider尺寸
		getSliderRect() {
			// 获取滑块条的尺寸信息
			setTimeout(() => {
				this.$uGetRect(".v-slider").then((rect) => {
					this.sliderRect = rect;
					this.updateSliderPlacement(this.value, true);
				});
			}, 10);
		},
		// 是否可以操作
		canNotDo() {
			return this.disabled;
		},
		// 获取当前手势点的X轴位移值
		getTouchX(e) {
			return e.touches[0].clientX;
		},
		formatStep(value) {
			// 移动点占总长度的百分比
			return (
				Math.round(
					Math.max(this.min, Math.min(value, this.max)) / this.step
				) * this.step
			);
		},
		// 发出事件
		emitEvent(event, value) {
			this.$emit(event, value || this.value);
		},
		// 标记当前手势的状态
		setTouchStatus(status) {
			this.status = status;
		},
		onTouchStart(e) {
			if (this.canNotDo()) {
				return;
			}
			// 标示当前的状态为开始触摸滑动
			this.emitEvent("start");
			this.setTouchStatus("start");
		},
		onTouchMove(e) {
			if (this.canNotDo()) {
				return;
			}
			// 滑块的左边不一定跟屏幕左边接壤，所以需要减去最外层父元素的左边值
			const x = this.getTouchX(e);
			const { left, width } = this.sliderRect;
			const distanceX = x - left;
			// 获得移动距离对整个滑块的百分比值，此为带有多位小数的值，不能用此更新视图
			// 否则造成通信阻塞，需要每改变一个step值时修改一次视图
			const percent = (distanceX / width) * 100;
			this.setTouchStatus("moving");
			this.updateSliderPlacement(percent, true, "moving");
		},
		onTouchEnd() {
			if (this.canNotDo()) {
				return;
			}
			this.emitEvent("end");
			this.setTouchStatus("end");
		},
		// 设置滑点的位置
		updateSliderPlacement(value, drag, event) {
			// 去掉小数部分，同时也是对step步进的处理
			const { width } = this.sliderRect;
			const percent = this.formatStep(value);
			// 设置移动的值
			const barStyle = {
				width: `${(percent / 100) * width}px`,
			};
			// 移动期间无需过渡动画
			if (drag === true) {
				barStyle.transition = "none";
			} else {
				// 非移动期间，删掉对过渡为空的声明，让css中的声明起效
				delete barStyle.transition;
			}
			// 修改value值
			this.$emit("input", percent);
			// 事件的名称
			if (event) {
				this.emitEvent(event, percent);
			}
			this.barStyle = barStyle;
		},
		onClick(e) {
			if (this.canNotDo()) {
				return;
			}
			// 直接点击滑块的情况，计算方式与onTouchMove方法相同
			const { left, width } = this.sliderRect;
			const value = ((e.detail.x - left) / width) * 100;
			this.updateSliderPlacement(value, false, "click");
		},
	},
};
